package org.stvd.core.jdbc.sequence;

import java.util.List;

import org.stvd.core.jdbc.DbUtil;

public class KeyInfo {

    /*
     * 序列主键名称
     */
    private String keyname;
    /*
     * 序列值
     */
    private long keyvalue;
    /*
     * 每次增加的步长，默认是1
     */
    private int stepvalue = 1;

    // 当前Sequence载体的最大值
    private long maxKey = -1; 
    // 当前Sequence载体的最小值
    private long minKey; 
    // Sequence值缓存大小
    private int poolSize; 

    public KeyInfo() {
    }

    public KeyInfo(String keyName) {
        this.poolSize = 10;
        this.keyname = keyName;
        this.stepvalue = 1;
        retrieveFromDB(0);
    }

    public KeyInfo(String keyName, int poolSize) {
        this.poolSize = poolSize;
        this.keyname = keyName;
        this.stepvalue = 1;
        retrieveFromDB(0);
    }

    public KeyInfo(String keyName, int poolSize, int stepvalue) {
        this.poolSize = poolSize;
        this.keyname = keyName;
        this.stepvalue = stepvalue;
        retrieveFromDB(0);
    }

    public synchronized String getKeyname() {
        return keyname;
    }

    public synchronized void setKeyname(String keyname) {
        this.keyname = keyname;
    }

    public synchronized long getKeyvalue() {
        return keyvalue;
    }

    public synchronized void setKeyvalue(long keyvalue) {
        this.keyvalue = keyvalue;
    }

    public synchronized int getStepvalue() {
        return stepvalue;
    }

    public synchronized void setStepvalue(int stepvalue) {
        this.stepvalue = stepvalue;
    }

    public synchronized long getMaxKey() {
        return maxKey;
    }

    public synchronized void setMaxKey(long maxKey) {
        this.maxKey = maxKey;
    }

    public synchronized long getMinKey() {
        return minKey;
    }

    public synchronized void setMinKey(long minKey) {
        this.minKey = minKey;
    }

    public synchronized int getPoolSize() {
        return poolSize;
    }

    public synchronized void setPoolSize(int poolSize) {
        this.poolSize = poolSize;
    }

    /**
     * 获取下一个Sequence值
     * 
     * @return 下一个Sequence值
     * @throws SQLException
     */
    public synchronized long getKeyValue() {
        if (keyvalue >= maxKey) {
            try {
                retrieveFromDB(0L);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (keyvalue < minKey) {
            keyvalue = minKey;
        }
        keyvalue += stepvalue;
        return keyvalue;
    }

    private synchronized void retrieveFromDB(long startValue) {
        List<KeyInfo> list = DbUtil.find("SELECT keyvalue,stepvalue FROM KEYTABLE WHERE keyname=?",
                new Object[] { keyname }, KeyInfo.class);
        if (null == list || list.isEmpty()) {
            DbUtil.execute("INSERT INTO KEYTABLE(keyname,keyvalue,stepvalue) value(?,?,?)",
                    new Object[] { keyname, startValue + poolSize, stepvalue });
            maxKey = startValue + poolSize;
            minKey = startValue;
            keyvalue = minKey;
        } else {
            KeyInfo keyInfo = list.get(0);
            stepvalue = keyInfo.getStepvalue();
            maxKey = keyInfo.getKeyvalue() + poolSize;
            minKey = maxKey - poolSize;
            keyvalue = minKey;

            if (maxKey > -1) {
                DbUtil.execute("UPDATE KEYTABLE SET keyvalue=keyvalue+? WHERE keyname=?",
                        new Object[] { poolSize, keyname });
            }
        }
    }
}
